#pragma once
#include <iostream>
#include <vector>
#include <string>
#include <filesystem>
#include <memory>
#include "log.hpp"
#include "CommonTools.hpp"

// 1. 将所有满足条件文件的路径进行整合,全部放到一个vector
// 2. 依次遍历所有的vector, 将每个文件的数据都读取出来
// 3. 读取每一个文件 , 筛选出对应的title , content , url
// 4. 将所有文件的数据都这和到一个文件中

namespace filtertext_ns
{

    struct Web_Info
    {
        std::string _title;
        std::string _content;
        std::string _url;
    };

    using namespace Log_ns;

    class FilterText
    {
        bool Search_Correct_Path()
        {
            namespace fs = std::filesystem;
            if (!fs::exists(_root))
            {
                Log(Fatal) << "not find the root file";
                return false;
            }

            for (const auto &entry : fs::recursive_directory_iterator(_root))
            {
                fs::path path = entry.path();
                // 1. 文件是普通文件
                // 2. 文件后缀是.html
                // 3. 将文件插入到files_path中

                if (!fs::is_regular_file(path) || path.extension() != ".html")
                {
                    continue;
                }
                _files_path.push_back(path.c_str());
            }
            return true;
        }

        bool Get_Files_Text(const std::string &path, std::string &text)
        {
            std::ifstream ifs(path);
            if (!ifs.is_open())
            {
                return false;
            }
            std::string line;
            while (getline(ifs, line))
            {
                text += line;
            }
            return true;
        }

        bool Get_Title(const std::string &text, std::string &title)
        {
            static std::string title_header = "<title>";
            static std::string title_tail = "</title>";
            size_t begin = text.find(title_header);
            if (begin == std::string::npos)
            {
                return false;
            }
            begin += title_header.size();
            size_t end = text.find(title_tail);
            if (begin > end)
            {
                return false;
            }
            title = text.substr(begin, end - begin);
            return true;
        }

        bool Get_Content(const std::string &text, std::string &content)
        {
            enum state
            {
                LABLE,
                CONTENT
            };

            state s = LABLE;
            for (auto ch : text)
            {
                switch (s)
                {
                case LABLE:
                    if (ch == '>')
                    {
                        content += " ";
                        s = CONTENT;
                    }
                    break;

                case CONTENT:
                    if (ch == '<')
                        s = LABLE;
                    else
                        content += ch;
                    break;

                default:
                    break;
                }
            }
            return true;
        }

        bool Get_url(const std::string &path, std::string &url)
        {
            static std::string url_head = "https://www.boost.org/doc/libs/1_85_0/doc/html/";
            std::string url_tail = path.substr(_root.size());

            url = url_head + url_tail;
            return true;
        }

    public:
        FilterText(const std::string &root, const std::string tar_path)
            : _root(root), _tar_path(tar_path)
        {
        }
        ~FilterText() = default;

        void Fl_Text()
        {
            // 对该文件的数据进行处理
            // 1. 向将所有有效的路径放到files_path中
            if (!Search_Correct_Path())
            {
                Log(Fatal) << "no root diractory";
                exit(1);
            }

            Log(Info) << "All appropriate documents has been save";
            // 2. 读取每一个文件的内容 , 筛选出对应的title , content , url
            for (auto &path : _files_path)
            {
                std::shared_ptr<Web_Info> wb_ptr(new Web_Info);
                // 1. 遍历每一个文本, 将所有文件中的数据都读取出来
                std::string text;
                if (!Get_Files_Text(path, text))
                {
                    Log(Fatal);
                    continue;
                }

                // 2. 拆解title
                if (!Get_Title(text, wb_ptr->_title))
                {
                    Log(Fatal);

                    continue;
                }

                // 3. 拆解content
                if (!Get_Content(text, wb_ptr->_content))
                {
                    Log(Fatal);
                    continue;
                }

                // 4. 拆解url

                if (!Get_url(path, wb_ptr->_url))
                {
                    Log(Fatal);
                    continue;
                }

                _webs_info.push_back(wb_ptr);
            }
            Log(Info) << "All files title , content , url has been separate , the files num:" << _files_path.size();

            std::ofstream ofs(_tar_path, std::ios::out | std::ios::binary);
            // 3. 将所有信息都写入到一个新文件中
            for (auto &wb_ptr : _webs_info)
            {
                static std::string sep = "\3";
                static std::string line = "\n";

                std::string &title = wb_ptr->_title;
                std::string &content = wb_ptr->_content;
                std::string &url = wb_ptr->_url;

                ofs.write(title.c_str(), title.size());
                ofs.write(sep.c_str(), sep.size());

                ofs.write(content.c_str(), content.size());
                ofs.write(sep.c_str(), sep.size());

                ofs.write(url.c_str(), url.size());
                ofs.write(line.c_str(), line.size());
            }
            Log(Info) << "All files message has been writen into " << _tar_path;
        }

    private:
        std::string _root;
        std::string _tar_path;
        std::vector<std::string> _files_path;
        std::vector<std::shared_ptr<Web_Info>> _webs_info;
    };

};